/*
 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
 * All rights reserved. 
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 * 
 * Author: Adam Dunkels <adam@sics.se>
 *
 */
#include "client.h"

#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include <lwip/sockets.h>
#include "../../Driver/Debug/debug_driver.h"
#include <string.h>

static void client(void *thread_param)
{
  	int sock = -1;
  	struct sockaddr_in client_addr;
    struct timeval timeout;
  	ip4_addr_t ipaddr;
	ssize_t len;
  
  	uint8_t receive_buf[512];
  	uint8_t send_buf[]= "[WHT] This is a TCP Client test...\r\n";

  	PRINT_INFO("PC IP Addr:%d.%d.%d.%d \t Port:%d\r\n", DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3, DEST_PORT);
	// 192.168.0.181
  	IP4_ADDR(&ipaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3);

  	while (1)
  	{
    	sock = socket(AF_INET, SOCK_STREAM, 0);
    	if (sock < 0)
    	{
      		PRINT_ERR("Socket error\r\n");
      		vTaskDelay(100);
      		continue;
    	}

		timeout.tv_usec = 0;
		timeout.tv_sec = 2;   // 2秒
    	setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
    	timeout.tv_sec = 3;   // 3秒
		setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    	client_addr.sin_family = AF_INET;      
    	client_addr.sin_port = htons(DEST_PORT);   
    	client_addr.sin_addr.s_addr = ipaddr.addr;
    	memset(&client_addr.sin_zero, 0, sizeof(client_addr.sin_zero));    

    	if (connect(sock,  (struct sockaddr*)&client_addr, sizeof(struct sockaddr)) == -1) 
    	{
        	PRINT_ERR("Connect failed!\n");
        	closesocket(sock);
        	vTaskDelay(300);
        	continue;
    	}
    
    	PRINT_INFO("Connect to server successful!\n");
    
    	while (1)
    	{
			len = write(sock, send_buf, sizeof(send_buf));
      		if ( len == 0)
			{
				PRINT_INFO("PC Link Close\r\n");
				break;
			}
			else if (len < 0)
			{
				if (errno == EAGAIN || errno == EWOULDBLOCK)
				{
        			PRINT_ERR("Send Timeover\r\n");
    			}
				break;
			}
			
			memset(receive_buf, 0, sizeof(receive_buf));
			len = read(sock, receive_buf, sizeof(receive_buf));
			if (len > 0)
			{
				PRINT_INFO("receive data = %s\r\n", receive_buf);
			}
			else if (len == 0)
			{
				PRINT_INFO("PC Link Close\r\n");
				break;
			}
			else
			{
				if (errno == EAGAIN || errno == EWOULDBLOCK)
				{
					PRINT_ERR("Receive Timeover\r\n");
    			}
				break;
			}
   
      		vTaskDelay(10);
    	}
    
    	closesocket(sock);
  	}
}

void client_init(void)
{
  	sys_thread_new("LWIP_Client_Task", client, NULL, 512, 1);
}
